-- Alternates between which string (though,
-- numbers can be used, too) is returned.
-- Ex: for i = 1,5 do
--       printf("%s ", string.alternate("red", "blue")));
--     end
-- will output: red blue red blue red
--
-- Call again with no parameters [ string.alternate() ]
-- to reset the internal counter
local __alternateCounter = 0;
function string.alternate(...)
	local args = {...};

	if( #args == 0 ) then
		__alternateCounter = 0;
		return;
	end

	__alternateCounter = __alternateCounter + 1;
	if( __alternateCounter > #args ) then
		__alternateCounter = 1;
	end

	return args[__alternateCounter];
end


-- Removes multiple occurances of the provided string.
-- Ex: str = string.reduceMultiples("one/two//three///", "/")
-- Will result in: str = "one/two/three/"
function string.reduceMultiples(str, multStr)
	return string.gsub(str, multStr .. "+", multStr);
end


-- Converts slashes from one type to another.
-- If 'posix' is true, forward slash (/) will be used.
-- Otherwise, back slash (\) will be used.
-- Defaults to forward slash.
function string.fixSlashes(str, posix)
	if( posix == nil ) then posix = true; end;

	if( posix ) then
		str = string.gsub(str, "\\+", "/");
		str = string.gsub(str, "//+", "/");
	else
		str = string.gsub(str, "/+", "\\");
		str = string.gsub(str, "\\+", "\\");
	end

	return str;
end

-- Removes any unnecessary garbage from a
-- full path string, such as any '../',
-- and converts to the desired slash
-- format (if 'posix' is given).
function string.fixPath(str, posix)
	if( posix ~= nil ) then
		if( posix == true ) then
			str = string.fixSlashes(str, true);
			return string.gsub(str, "([%a%d%s%._]+)/%.%./", "");
		else
			str = string.fixSlashes(str, false);
			return string.gsub(str, "([%a%d%s%._]+)\\%.%.\\", "");
		end
	else
		str = string.gsub(str, "([%a%d%s%._]+)/%.%./", "");
		return string.gsub(str, "([%a%d%s%._]+)\\%.%.\\", "");
	end
end

-- Removes extra whitespace
function string.trim(str)
	return string.gsub(str, "^%s*(.-)%s*$", "%1");
end


-- Generates and returns a random hash as a string.
-- 'len' denotes the length, in characters. Default of 32.
--
-- '_type' can be one of the following string values:
--    alnum    : Alpha-numeric, upper and lowercase
--    letters  : Letters only, upper and lowercase
--    numeric  : Numbers only
--    nozero   : Numbers, no zero
--    special  : Alpa-numeric plus special characters
--
--  '_type' can also be a table containing the characters
--  you wish to use for more customization.
-- Default _type is "alnum"
local alnum, letters, numeric, nozero, special;
function string.randomhash(len, _type)
	len = len or 32;
	_type = _type or "alnum";

	if( type(_type) == "table" ) then
		hash_chars = _type;
	elseif( _type == "alnum" ) then
		hash_chars = alnum;
	elseif( _type == "letters" ) then
		hash_chars = letters;
	elseif( _type == "numeric" ) then
		hash_chars = numeric;
	elseif( _type == "nozero" ) then
		hash_chars = nozero;
	elseif( _type == "special") then
		hash_chars = special;
	else
		hash_chars = alnum;
	end

  local holder = ""; -- a string for holding our hash temporarily
 
  for i = 1, len do
    local index = math.random(1, #hash_chars);
    holder = holder .. hash_chars[index];
  end
 
  return holder;
end

-- Table prep work for string.randomhash();
alnum = {};
letters = {};
numeric = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"};
nozero = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
special = {"!", "#", "$", "&", "*", "_", "?", "^", "@"};

for i = 65, 90 do
	table.insert(alnum, string.char(i));
	table.insert(letters, string.char(i));
	table.insert(special, string.char(i));
end
for i = 97,122 do
	table.insert(alnum, string.char(i));
	table.insert(letters, string.char(i));
	table.insert(special, string.char(i));
end
for i = 48,57 do
	table.insert(alnum, string.char(i));
	table.insert(special, string.char(i));
end
-- ENDOF: string.randomhash();